/**
 *******************************************************************************
 * @file  usb_dev_audio_class.h
 * @brief Head file for usb_dev_audio_class.c
 @verbatim
   Change Logs:
   Date             Author          Notes
   2021-03-29       Linsq           First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by HDSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */
#ifndef __USB_DEV_AUDIO_CLASS_H__
#define __USB_DEV_AUDIO_CLASS_H__

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "usb_dev_ctrleptrans.h"
#include "usb_dev_stdreq.h"
#include "usb_dev_desc.h"
#include "hc32_common.h"

/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
#define AUDIO_OUT_PACKET                              (uint32_t)(((USBD_AUDIO_FREQ * 3 * 2) /1000)) 
#define AUDIO_IN_PACKET                               (uint32_t)((USBD_AUDIO_FREQ * 3 * 2) /1000)
/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
  that it is an even number and higher than 3 */
#define OUT_PACKET_NUM                                   8
#define IN_PACKET_NUM                                    8

#define MIC_IT_ID           0x01
#define MIC_FU_ID           0x02
#define MIC_OT_ID           0x03

#define SPK_IT_ID           0x04
#define SPK_FU_ID           0x05
#define SPK_OT_ID           0x06


/* Total size of the audio transfer buffer */
#define AUDIO_IN_SAMPLE_NUM                           96 //Sampling number per second corresponding to 48KHz  
#define TOTAL_OUT_BUF_SIZE                           ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM))
#define TOTAL_IN_BUF_SIZE                            ((uint32_t)(AUDIO_IN_SAMPLE_NUM * IN_PACKET_NUM))
#define AUDIO_CONFIG_DESC_SIZE                        199

#define AUDIO_INTERFACE_DESC_SIZE                     9
#define USB_AUDIO_DESC_SIZ                            0x09
#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE             0x09
#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE            0x07

#define AUDIO_DESCRIPTOR_TYPE                         0x21
#define USB_DEVICE_CLASS_AUDIO                        0x01
#define AUDIO_SUBCLASS_AUDIOCONTROL                   0x01
#define AUDIO_SUBCLASS_AUDIOSTREAMING                 0x02
#define AUDIO_PROTOCOL_UNDEFINED                      0x00
#define AUDIO_STREAMING_GENERAL                       0x01
#define AUDIO_STREAMING_FORMAT_TYPE                   0x02

/* Audio Descriptor Types */
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE               0x24
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE                0x25

/* Audio Control Interface Descriptor Subtypes */
#define AUDIO_CONTROL_HEADER                          0x01
#define AUDIO_CONTROL_INPUT_TERMINAL                  0x02
#define AUDIO_CONTROL_OUTPUT_TERMINAL                 0x03
#define AUDIO_CONTROL_FEATURE_UNIT                    0x06

#define AUDIO_INPUT_TERMINAL_DESC_SIZE                0x0C
#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE               0x09
#define AUDIO_STREAMING_INTERFACE_DESC_SIZE           0x07

#define AUDIO_CONTROL_MUTE                            0x0001

#define AUDIO_FORMAT_TYPE_I                           0x01
#define AUDIO_FORMAT_TYPE_III                         0x03

#define USB_ENDPOINT_TYPE_ISOCHRONOUS                 0x01
#define AUDIO_ENDPOINT_GENERAL                        0x01

#define AUDIO_REQ_GET_CUR                             0x81
#define AUDIO_REQ_SET_CUR                             0x01

#define AUDIO_OUT_STREAMING_CTRL                      0x02


typedef struct _Audio_Fops
{
    void     (*Init)         (void);
    void     (*DeInit)       (void);
    uint8_t  (*AudioCmd)     (uint8_t* pbuf, uint32_t size, uint8_t cmd);
    uint8_t  (*VolumeCtl)    (uint8_t vol);
    uint8_t  (*MuteCtl)      (uint8_t cmd);
    uint8_t  (*PeriodicTC)   (uint8_t cmd);
    uint8_t  (*GetState)     (void);
}AUDIO_FOPS_TypeDef;


#define AUDIO_PACKET_SZE(frq)          (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \
                                       (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF)
#define SAMPLE_FREQ(frq)               (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))

#define WBVAL(x)  (x & 0xFF), ((x >> 8) & 0xFF)
#define B3VAL(x)  (x & 0xFF), ((x >> 8) & 0xFF), ((x >> 16) & 0xFF)


extern uint32_t  IsocInBuff[TOTAL_IN_BUF_SIZE * 1];
extern uint32_t* IsocInWrPtr;
extern uint32_t* IsocInRdPtr;
extern uint16_t  IsocInWrCnt, IsocInRdCnt;

extern usb_dev_class_func  AUDIO_cb;

extern void Data_Out_Process(void *pdev, uint8_t epnum);
extern void Sof_Process(void *pdev);

#endif  // __USB_DEV_AUDIO_CLASS_H__ 

